package com.sina.shop.manage.service.menu;

import com.sina.shop.core.exception.client.DataException;
import com.sina.shop.core.exception.server.CreateException;
import com.sina.shop.core.exception.server.ResourceExistsException;
import com.sina.shop.core.exception.server.UpdateException;
import com.sina.shop.domain.menu.Menu;
import com.sina.shop.manage.dao.menu.MenuManageDao;
import com.sina.shop.service.ShopDataSourceService;
import com.sina.shop.util.Assert;
import com.sina.shop.util.CollectionUtils;
import com.sina.shop.util.ResultCode;
import com.sina.shop.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

import static com.sina.shop.service.ServiceConstant.SHOP_TX;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * 段浩杰   2018-01-03-10:37
 */
@Service("menuManageService")
public class MenuManageServiceImpl extends ShopDataSourceService implements MenuManageService {

    @Autowired
    @Qualifier("menuManageDao")
    private MenuManageDao menuManageDao;

    @Override
    @Transactional(value = SHOP_TX, readOnly = true, isolation = Isolation.READ_COMMITTED)
    public Menu getMenuByName(String name) {
        return menuManageDao.getMenuByName(name);
    }

    @Override
    @Transactional(value = SHOP_TX, readOnly = true, isolation = Isolation.READ_COMMITTED)
    public Menu getMenuById(Long id) {
        return menuManageDao.get(Menu.class, id);
    }

    @Override
    @Transactional(value = SHOP_TX, isolation = Isolation.REPEATABLE_READ)
    public int deleteMenu(Long id) throws DataException, UpdateException {
        Menu menu = menuManageDao.get(Menu.class, id);
        Assert.assertNotNull(menu, "Menu[id=%s] not exists", menu.getId());

        try {
            return menuManageDao.deleteMenu(id);
        } catch (DataAccessException e) {
            LOG.error(" {} delete Menu error.", Menu.class, e);
            throw new UpdateException(ResultCode.dataAccessError, e.getMessage(), e);
        }
    }

    @Override
    @Transactional(value = SHOP_TX, isolation = Isolation.READ_COMMITTED)
    public Menu saveMenu(Menu menu) throws CreateException, ResourceExistsException, DataException {
        boolean exists;
        exists = menuManageDao.isExistsByUnique(Menu.class, "name", menu.getName());
        Assert.assertFalse(exists, ResourceExistsException.class, ResultCode.dataExists
                , "Menu[%s] exists", menu.getName());

        try {
            menuManageDao.save(menu);
            menuManageDao.flush();
            return menu;
        } catch (DataAccessException e) {
            LOG.error(" {} save Menu error.", Menu.class, e);
            throw new UpdateException(ResultCode.dataAccessError, e.getMessage(), e);
        }
    }

    @Override
    @Transactional(value = SHOP_TX, isolation = Isolation.REPEATABLE_READ)
    public Menu updateMenu(Menu menu) throws UpdateException, DataException {
        Menu m = menuManageDao.get(Menu.class, menu.getId());
        Assert.assertNotNull(m, "Menu[id=%s] not exists", menu.getId());

        try {
            m = updateMenuFiled(menu, m);
            menuManageDao.flush();

            return m;
        } catch (DataAccessException e) {
            LOG.error(" {} update Menu error.", Menu.class, e);
            throw new UpdateException(ResultCode.dataAccessError, e.getMessage(), e);
        }

    }

    private Menu updateMenuFiled(Menu oldMenu, Menu newMenu) throws CreateException {

        if (!StringUtils.isEmpty(oldMenu.getName())) {
            newMenu.setName(oldMenu.getName());
        }
        if (oldMenu.getSort() != null) {
            newMenu.setSort(oldMenu.getSort());
        }
        if (!StringUtils.isEmpty(oldMenu.getType())) {
            newMenu.setType(oldMenu.getType());
        }
        /*if (!StringUtils.isEmpty(oldMenu.getCreateName())) {
            newMenu.setCreateName(oldMenu.getCreateName());
        }*/
        if (oldMenu.getUpdateTime() != null) {
            newMenu.setUpdateTime(oldMenu.getUpdateTime());
        }
        if (oldMenu.getMenu() != null) {
            newMenu.setMenu(oldMenu.getMenu());
        }
        if (!CollectionUtils.isEmpty(oldMenu.getMenus())) {
            newMenu.setMenus(oldMenu.getMenus());
        }

        return newMenu;
    }

    @Override
    @Transactional(value = SHOP_TX, readOnly = true, isolation = Isolation.READ_COMMITTED)
    public List<Map<String, Object>> getMenuList(Menu menu, Long[] count) {

        if (count != null && count.length > 0) {
            count[0] = menuManageDao.getMenuCount(menu);
        }

        return menuManageDao.getMenuList(menu);
    }

    @Override
    @Transactional(value = SHOP_TX, readOnly = true, isolation = Isolation.READ_COMMITTED)
    public List<Map<String, Object>> getMenuIdAndNameList(Boolean hasAll) {
        return menuManageDao.getMenuIdAndNameList(hasAll);
    }
}
